home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume11 / id / part02 < prev    next >
Encoding:
Internet Message Format  |  1987-09-25  |  39.7 KB

  1. Subject:  v11i079:  C cross-reference database system, Part02/03
  2. Newsgroups: comp.sources.unix
  3. Sender: sources
  4. Approved: rs@uunet.UU.NET
  5.  
  6. Submitted-by: sun!suneast!kumquat!gmcgary (Greg Mcgary - Sun ECD Software)
  7. Posting-number: Volume 11, Issue 79
  8. Archive-name: id/Part02
  9.  
  10.  
  11.  
  12. #! /bin/sh
  13. # This is a shell archive, meaning:
  14. # 1. Remove everything above the #! /bin/sh line.
  15. # 2. Save the resulting text in a file.
  16. # 3. Execute the file with /bin/sh (not csh) to create the files:
  17. #    basename.c
  18. #    bitcount.c
  19. #    bitops.c
  20. #    bitsvec.c
  21. #    bsearch.c
  22. #    bzero.c
  23. #    document.c
  24. #    fid.c
  25. #    gets0.c
  26. #    getsFF.c
  27. #    getscan.c
  28. #    hash.c
  29. #    idx.c
  30. #    init.c
  31. #    lid.c
  32. export PATH; PATH=/bin:$PATH
  33. echo shar: extracting "'basename.c'" '(433 characters)'
  34. sed 's/^X//' << \SHAR_EOF > 'basename.c'
  35. X/* Copyright (c) 1986, Greg McGary */
  36. Xstatic char sccsid[] = "@(#)basename.c    1.1 86/10/09";
  37. X
  38. X#include    <string.h>
  39. X
  40. Xchar *basename();
  41. Xchar *dirname();
  42. X
  43. Xchar *
  44. Xbasename(path)
  45. X    char        *path;
  46. X{
  47. X    char        *base;
  48. X
  49. X    if ((base = strrchr(path, '/')) == 0)
  50. X        return path;
  51. X    else
  52. X        return ++base;
  53. X}
  54. X
  55. Xchar *
  56. Xdirname(path)
  57. X    char        *path;
  58. X{
  59. X    char        *base;
  60. X
  61. X    if ((base = strrchr(path, '/')) == 0)
  62. X        return ".";
  63. X    else
  64. X        return strnsav(path, base - path);
  65. X}
  66. SHAR_EOF
  67. if test 433 -ne "`wc -c < 'basename.c'`"
  68. then
  69.     echo shar: error transmitting "'basename.c'" '(should have been 433 characters)'
  70. fi
  71. echo shar: extracting "'bitcount.c'" '(643 characters)'
  72. sed 's/^X//' << \SHAR_EOF > 'bitcount.c'
  73. X/* Copyright (c) 1986, Greg McGary */
  74. Xstatic char sccsid[] = "@(#)bitcount.c    1.1 86/10/09";
  75. X
  76. Xint bitCount();
  77. Xint bitsCount();
  78. X
  79. X/*
  80. X    Count the number of 1 bits in the given integer.
  81. X*/
  82. Xstatic char bitcnt[] = {
  83. X/*    0 1 2 3 4 5 6 7    8 9 a b c d e f    */
  84. X    0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4
  85. X};
  86. Xint
  87. XbitCount(mask)
  88. X    register unsigned    mask;
  89. X{
  90. X    register int    nybbles = 8;
  91. X    register int    cnt = 0;
  92. X
  93. X    while (mask && nybbles--) {
  94. X        cnt += bitcnt[mask&0xf];
  95. X        mask >>= 4;
  96. X    }
  97. X    return cnt;
  98. X}
  99. X
  100. Xint
  101. XbitsCount(bitv, n)
  102. X    register char    *bitv;
  103. X    register int    n;
  104. X{
  105. X    register int    count = 0;
  106. X
  107. X    while (n--) {
  108. X        count += bitcnt[*bitv&0xf] + bitcnt[(*bitv>>4)&0xf];
  109. X        bitv++;
  110. X    }
  111. X}
  112. SHAR_EOF
  113. if test 643 -ne "`wc -c < 'bitcount.c'`"
  114. then
  115.     echo shar: error transmitting "'bitcount.c'" '(should have been 643 characters)'
  116. fi
  117. echo shar: extracting "'bitops.c'" '(992 characters)'
  118. sed 's/^X//' << \SHAR_EOF > 'bitops.c'
  119. X/* Copyright (c) 1986, Greg McGary */
  120. Xstatic char sccsid[] = "@(#)bitops.c    1.1 86/10/09";
  121. X
  122. X#include    <bitops.h>
  123. X
  124. Xchar *bitsset();
  125. Xchar *bitsclr();
  126. Xchar *bitsand();
  127. Xchar *bitsxor();
  128. Xint bitstst();
  129. Xint bitsany();
  130. X
  131. Xchar *
  132. Xbitsset(s1, s2, n)
  133. X    register char    *s1;
  134. X    register char    *s2;
  135. X    register int    n;
  136. X{
  137. X    while (n--)
  138. X        *s1++ |= *s2++;
  139. X
  140. X    return s1;
  141. X}
  142. X
  143. Xchar *
  144. Xbitsclr(s1, s2, n)
  145. X    register char    *s1;
  146. X    register char    *s2;
  147. X    register int    n;
  148. X{
  149. X    while (n--)
  150. X        *s1++ &= ~*s2++;
  151. X
  152. X    return s1;
  153. X}
  154. X
  155. Xchar *
  156. Xbitsand(s1, s2, n)
  157. X    register char    *s1;
  158. X    register char    *s2;
  159. X    register int    n;
  160. X{
  161. X    while (n--)
  162. X        *s1++ &= *s2++;
  163. X
  164. X    return s1;
  165. X}
  166. X
  167. Xchar *
  168. Xbitsxor(s1, s2, n)
  169. X    register char    *s1;
  170. X    register char    *s2;
  171. X    register int    n;
  172. X{
  173. X    while (n--)
  174. X        *s1++ ^= *s2++;
  175. X
  176. X    return s1;
  177. X}
  178. X
  179. Xint
  180. Xbitstst(s1, s2, n)
  181. X    register char    *s1;
  182. X    register char    *s2;
  183. X    register int    n;
  184. X{
  185. X    while (n--)
  186. X        if (*s1++ & *s2++)
  187. X            return 1;
  188. X
  189. X    return 0;
  190. X}
  191. X
  192. Xint
  193. Xbitsany(s, n)
  194. X    register char    *s;
  195. X    register int    n;
  196. X{
  197. X    while (n--)
  198. X        if (*s++)
  199. X            return 1;
  200. X
  201. X    return 0;
  202. X}
  203. SHAR_EOF
  204. if test 992 -ne "`wc -c < 'bitops.c'`"
  205. then
  206.     echo shar: error transmitting "'bitops.c'" '(should have been 992 characters)'
  207. fi
  208. echo shar: extracting "'bitsvec.c'" '(1614 characters)'
  209. sed 's/^X//' << \SHAR_EOF > 'bitsvec.c'
  210. X/* Copyright (c) 1986, Greg McGary */
  211. Xstatic char sccsid[] = "@(#)bitsvec.c    1.1 86/10/09";
  212. X
  213. X#include    <stdio.h>
  214. X#include    <bitops.h>
  215. X#include    <string.h>
  216. X#include    <extern.h>
  217. X#include    <id.h>
  218. X
  219. Xint vecToBits();
  220. Xint bitsToVec();
  221. Xchar *intToStr();
  222. Xint getsFF();
  223. Xint strToInt();
  224. Xvoid skipFF();
  225. X
  226. Xint
  227. XvecToBits(bitArray, vec, size)
  228. X    register char    *bitArray;
  229. X    register char    *vec;
  230. X    int        size;
  231. X{
  232. X    register int    i;
  233. X    int        count;
  234. X
  235. X    for (count = 0; (*vec & 0xff) != 0xff; count++) {
  236. X        i = strToInt(vec, size);
  237. X        BITSET(bitArray, i);
  238. X        vec += size;
  239. X    }
  240. X    return count;
  241. X}
  242. X
  243. Xint
  244. XbitsToVec(vec, bitArray, bitCount, size)
  245. X    register char    *vec;
  246. X    char        *bitArray;
  247. X    int        bitCount;
  248. X    int        size;
  249. X{
  250. X    register char    *element;
  251. X    register int    i;
  252. X    int        count;
  253. X
  254. X    for (count = i = 0; i < bitCount; i++) {
  255. X        if (!BITTST(bitArray, i))
  256. X            continue;
  257. X        element = intToStr(i, size);
  258. X        switch (size) {
  259. X        case 4: *vec++ = *element++;
  260. X        case 3: *vec++ = *element++;
  261. X        case 2: *vec++ = *element++;
  262. X        case 1: *vec++ = *element++;
  263. X        }
  264. X        count++;
  265. X    }
  266. X    *vec++ = 0xff;
  267. X
  268. X    return count;
  269. X}
  270. X
  271. Xchar *
  272. XintToStr(i, size)
  273. X    register int    i;
  274. X    int        size;
  275. X{
  276. X    static char    buf0[4];
  277. X    register char    *bufp = &buf0[size];
  278. X
  279. X    switch (size)
  280. X    {
  281. X    case 4:    *--bufp = (i & 0xff); i >>= 8;
  282. X    case 3: *--bufp = (i & 0xff); i >>= 8;
  283. X    case 2: *--bufp = (i & 0xff); i >>= 8;
  284. X    case 1: *--bufp = (i & 0xff);
  285. X    }
  286. X    return buf0;
  287. X}
  288. X
  289. Xint
  290. XstrToInt(bufp, size)
  291. X    register char    *bufp;
  292. X    int        size;
  293. X{
  294. X    register int    i = 0;
  295. X
  296. X    bufp--;
  297. X    switch (size)
  298. X    {
  299. X    case 4: i |= (*++bufp & 0xff); i <<= 8;
  300. X    case 3: i |= (*++bufp & 0xff); i <<= 8;
  301. X    case 2: i |= (*++bufp & 0xff); i <<= 8;
  302. X    case 1: i |= (*++bufp & 0xff);
  303. X    }
  304. X    return i;
  305. X}
  306. SHAR_EOF
  307. if test 1614 -ne "`wc -c < 'bitsvec.c'`"
  308. then
  309.     echo shar: error transmitting "'bitsvec.c'" '(should have been 1614 characters)'
  310. fi
  311. echo shar: extracting "'bsearch.c'" '(692 characters)'
  312. sed 's/^X//' << \SHAR_EOF > 'bsearch.c'
  313. X/* Copyright (c) 1986, Greg McGary */
  314. Xstatic char sccsid[] = "@(#)bsearch.c    1.1 86/10/09";
  315. X
  316. Xchar *bsearch();
  317. X
  318. X/*
  319. X    Binary search -- from Knuth (6.2.1) Algorithm B
  320. X*/
  321. Xchar *
  322. Xbsearch(key, base, nel, width, compar)
  323. X    char        *key;
  324. X    register char    *base;
  325. X    unsigned int    nel;
  326. X    int        width;
  327. X    int        (*compar)();
  328. X{
  329. X    register char    *last;
  330. X    register char    *position;
  331. X    register int    result;
  332. X    int        width2;
  333. X
  334. X    width2 = width * 2;
  335. X    last = &base[width * (nel - 1)];
  336. X
  337. X    while (last >= base) {
  338. X        position = &base[width * ((last - base)/width2)];
  339. X        
  340. X        if ((result = (*compar)(key, position)) == 0)
  341. X            return position;
  342. X        if (result < 0)
  343. X            last = position - width;
  344. X        else
  345. X            base = position + width;
  346. X    }
  347. X    return (char *)0;
  348. X}
  349. SHAR_EOF
  350. if test 692 -ne "`wc -c < 'bsearch.c'`"
  351. then
  352.     echo shar: error transmitting "'bsearch.c'" '(should have been 692 characters)'
  353. fi
  354. echo shar: extracting "'bzero.c'" '(199 characters)'
  355. sed 's/^X//' << \SHAR_EOF > 'bzero.c'
  356. X/* Copyright (c) 1986, Greg McGary */
  357. Xstatic char sccsid[] = "@(#)bzero.c    1.1 86/10/09";
  358. X
  359. Xvoid bzero();
  360. X
  361. Xvoid
  362. Xbzero(s, n)
  363. X    register char    *s;
  364. X    register int    n;
  365. X{
  366. X    if (n) do
  367. X        *s++ = 0;
  368. X    while (--n);
  369. X}
  370. SHAR_EOF
  371. if test 199 -ne "`wc -c < 'bzero.c'`"
  372. then
  373.     echo shar: error transmitting "'bzero.c'" '(should have been 199 characters)'
  374. fi
  375. echo shar: extracting "'document.c'" '(188 characters)'
  376. sed 's/^X//' << \SHAR_EOF > 'document.c'
  377. X/* Copyright (c) 1986, Greg McGary */
  378. Xstatic char sccsid[] = "@(#)document.c    1.1 86/10/09";
  379. X
  380. Xvoid document();
  381. X
  382. Xvoid
  383. Xdocument(doc)
  384. X    char        **doc;
  385. X{
  386. X    while (*doc)
  387. X        printf("%s\n", *doc++);
  388. X}
  389. SHAR_EOF
  390. if test 188 -ne "`wc -c < 'document.c'`"
  391. then
  392.     echo shar: error transmitting "'document.c'" '(should have been 188 characters)'
  393. fi
  394. echo shar: extracting "'fid.c'" '(2362 characters)'
  395. sed 's/^X//' << \SHAR_EOF > 'fid.c'
  396. Xstatic char copyright[] = "@(#)Copyright (c) 1986, Greg McGary";
  397. Xstatic char sccsid[] = "@(#)fid.c    1.2 86/10/17";
  398. X
  399. X#include    <bool.h>
  400. X#include    <stdio.h>
  401. X#include    <string.h>
  402. X#include    <ctype.h>
  403. X#include    <radix.h>
  404. X#include    <id.h>
  405. X#include    <bitops.h>
  406. X#include    <extern.h>
  407. X
  408. Xvoid fileId();
  409. X
  410. XFILE        *IdFILE;
  411. Xstruct idhead    Idh;
  412. Xstruct idarg    *IdArgs;
  413. X
  414. Xchar *MyName;
  415. Xstatic void
  416. Xusage()
  417. X{
  418. X    fprintf(stderr, "Usage: %s [-f<file>] file1 file2\n", MyName);
  419. X    exit(1);
  420. X}
  421. Xmain(argc, argv)
  422. X    int        argc;
  423. X    char        **argv;
  424. X{
  425. X    char        *idFile = IDFILE;
  426. X    char        *arg;
  427. X    float        occurPercent = 0.0;
  428. X    int        occurNumber = 0;
  429. X    int        op;
  430. X
  431. X    MyName = basename(GETARG(argc, argv));
  432. X
  433. X    while (argc) {
  434. X        arg = GETARG(argc, argv);
  435. X        switch (op = *arg++)
  436. X        {
  437. X        case '-':
  438. X        case '+':
  439. X            break;
  440. X        default:
  441. X            UNGETARG(argc, argv);
  442. X            goto argsdone;
  443. X        }
  444. X        while (*arg) switch (*arg++)
  445. X        {
  446. X        case 'f': idFile = arg; goto nextarg;
  447. X        default: usage();
  448. X        }
  449. X    nextarg:;
  450. X    }
  451. Xargsdone:
  452. X
  453. X    idFile = spanPath(getDirToName(idFile), idFile);
  454. X    if ((IdFILE = initID(idFile, &Idh, &IdArgs)) == NULL) {
  455. X        filerr("open", idFile);
  456. X        exit(1);
  457. X    }
  458. X
  459. X    if (argc < 1 || argc > 2)
  460. X        usage();
  461. X
  462. X    fileId(argc, argv);
  463. X    exit(0);
  464. X}
  465. X
  466. Xvoid
  467. XfileId(argc, argv)
  468. X    int        argc;
  469. X    char        **argv;
  470. X{
  471. X    char        *buf;
  472. X    int        want, got;
  473. X    int        bitoff[2];
  474. X    int        i, j;
  475. X    int        argLength;
  476. X    int        pathLength;
  477. X    int        lengthDiff;
  478. X    char        *pathVec;
  479. X    register struct idarg    *idArgs;
  480. X
  481. X    want = 0;
  482. X    for (j = 0; j < argc; j++, argv++) {
  483. X        want |= (1<<j);
  484. X        argLength = strlen(*argv);
  485. X        bitoff[j] = -1;
  486. X        for (idArgs = IdArgs, i = 0; i < Idh.idh_pthc; i++, idArgs++) {
  487. X            pathLength = strlen(idArgs->ida_arg);
  488. X            if (argLength > pathLength)
  489. X                continue;
  490. X            lengthDiff = pathLength - argLength;
  491. X            if (strequ(&idArgs->ida_arg[lengthDiff], *argv)) {
  492. X                bitoff[j] = i;
  493. X                break;
  494. X            }
  495. X        }
  496. X        if (bitoff[j] < 0) {
  497. X            fprintf(stderr, "%s: not found\n", *argv);
  498. X            exit(1);
  499. X        }
  500. X    }
  501. X
  502. X    buf = malloc((int)Idh.idh_bsiz);
  503. X    fseek(IdFILE, Idh.idh_namo, 0);
  504. X
  505. X    for (i = 0; i < Idh.idh_namc; i++) {
  506. X        pathVec = 1 + buf + fgets0(buf, Idh.idh_bsiz, IdFILE);
  507. X        getsFF(pathVec, IdFILE);
  508. X        got = 0;
  509. X        while ((*pathVec & 0xff) != 0xff) {
  510. X            j = strToInt(pathVec, Idh.idh_vecc);
  511. X            if ((want & (1<<0)) && j == bitoff[0])
  512. X                got |= (1<<0);
  513. X            if ((want & (1<<1)) && j == bitoff[1])
  514. X                got |= (1<<1);
  515. X            if (got == want) {
  516. X                printf("%s\n", ID_STRING(buf));
  517. X                break;
  518. X            }
  519. X            pathVec += Idh.idh_vecc;
  520. X        }
  521. X    }
  522. X}
  523. SHAR_EOF
  524. if test 2362 -ne "`wc -c < 'fid.c'`"
  525. then
  526.     echo shar: error transmitting "'fid.c'" '(should have been 2362 characters)'
  527. fi
  528. echo shar: extracting "'gets0.c'" '(575 characters)'
  529. sed 's/^X//' << \SHAR_EOF > 'gets0.c'
  530. X/* Copyright (c) 1986, Greg McGary */
  531. Xstatic char sccsid[] = "@(#)gets0.c    1.1 86/10/09";
  532. X
  533. X#include    <stdio.h>
  534. X
  535. Xint fgets0();
  536. X
  537. X/*
  538. X    This is like fgets(3s), except that lines are
  539. X    delimited by NULs rather than newlines.  Also,
  540. X    we return the number of characters gotten rather
  541. X    than the address of buf0.
  542. X*/
  543. Xint
  544. Xfgets0(buf0, size, inFILE)
  545. X    char        *buf0;
  546. X    int        size;
  547. X    register FILE    *inFILE;
  548. X{
  549. X    register char    *buf;
  550. X    register int    c;
  551. X    register char    *end;
  552. X
  553. X    buf = buf0;
  554. X    end = &buf[size];
  555. X    while ((c = getc(inFILE)) > 0 && buf < end)
  556. X        *buf++ = c;
  557. X    *buf = '\0';
  558. X    return (buf - buf0);
  559. X}
  560. SHAR_EOF
  561. if test 575 -ne "`wc -c < 'gets0.c'`"
  562. then
  563.     echo shar: error transmitting "'gets0.c'" '(should have been 575 characters)'
  564. fi
  565. echo shar: extracting "'getsFF.c'" '(418 characters)'
  566. sed 's/^X//' << \SHAR_EOF > 'getsFF.c'
  567. X/* Copyright (c) 1986, Greg McGary */
  568. Xstatic char sccsid[] = "@(#)getsFF.c    1.1 86/10/09";
  569. X
  570. X#include    <stdio.h>
  571. X
  572. Xint getsFF();
  573. Xvoid skipFF();
  574. X
  575. Xint
  576. XgetsFF(buf0, inFILE)
  577. X    char        *buf0;
  578. X    register FILE    *inFILE;
  579. X{
  580. X    register char    *buf = buf0;
  581. X
  582. X    while (((*buf++ = getc(inFILE)) & 0xff) != 0xff)
  583. X        ;
  584. X    return (buf - buf0 - 1);
  585. X}
  586. X
  587. Xvoid
  588. XskipFF(inFILE)
  589. X    register FILE    *inFILE;
  590. X{
  591. X    while ((getc(inFILE) & 0xff) != 0xff)
  592. X        ;
  593. X    return;
  594. X}
  595. SHAR_EOF
  596. if test 418 -ne "`wc -c < 'getsFF.c'`"
  597. then
  598.     echo shar: error transmitting "'getsFF.c'" '(should have been 418 characters)'
  599. fi
  600. echo shar: extracting "'getscan.c'" '(5672 characters)'
  601. sed 's/^X//' << \SHAR_EOF > 'getscan.c'
  602. X/* Copyright (c) 1986, Greg McGary */
  603. Xstatic char sccsid[] = "@(#)getscan.c    1.1 86/10/09";
  604. X
  605. X#include    <stdio.h>
  606. X#include    <string.h>
  607. X#include    <id.h>
  608. X#include    <ctype.h>
  609. X#include    <extern.h>
  610. X
  611. Xchar *getLanguage();
  612. Xchar *(*getScanner())();
  613. Xvoid setScanArgs();
  614. X
  615. Xstatic struct sufftab *suffSlot();
  616. Xstatic struct langtab *langSlot();
  617. Xstatic void sorryNoScan();
  618. X
  619. Xvoid setAdaArgs(lang) { sorryNoScan(lang); }
  620. Xchar *getAdaId() { setAdaArgs("ada"); return NULL; }
  621. X
  622. Xvoid setPascalArgs(lang) { sorryNoScan(lang); }
  623. Xchar *getPascalId() { setPascalArgs("pascal"); return NULL; }
  624. X
  625. Xvoid setTextArgs(lang) { sorryNoScan(lang); }
  626. Xchar *getTextId() { setTextArgs("plain text"); return NULL; }
  627. X
  628. Xvoid setRoffArgs(lang) { sorryNoScan(lang); }
  629. Xchar *getRoffId() { setRoffArgs("[nt]roff"); return NULL; }
  630. X
  631. Xvoid setTeXArgs(lang) { sorryNoScan(lang); }
  632. Xchar *getTeXId() { setTeXArgs("TeX"); return NULL; }
  633. X
  634. Xvoid setLispArgs(lang) { sorryNoScan(lang); }
  635. Xchar *getLispId() { setLispArgs("lisp"); return NULL; }
  636. X
  637. Xstruct langtab {
  638. X    struct langtab    *lt_next;
  639. X    char    *lt_name;
  640. X    char    *(*lt_getid)();
  641. X    void    (*lt_setargs)();
  642. X};
  643. X
  644. Xstruct sufftab {
  645. X    struct sufftab    *st_next;
  646. X    char    *st_suffix;
  647. X    struct langtab *st_lang;
  648. X};
  649. X
  650. X
  651. Xstruct langtab langtab[] = {
  652. X#define    SCAN_C        (&langtab[0])
  653. X{    &langtab[1],    "c",        getCId,        setCArgs    },
  654. X#define    SCAN_ASM    (&langtab[1])
  655. X{    &langtab[2],    "asm",        getAsmId,    setAsmArgs    },
  656. X#define    SCAN_ADA    (&langtab[2])
  657. X{    &langtab[3],    "ada",        getAdaId,    setAdaArgs    },
  658. X#define    SCAN_PASCAL    (&langtab[3])
  659. X{    &langtab[4],    "pascal",    getPascalId,    setPascalArgs    },
  660. X#define    SCAN_LISP    (&langtab[4])
  661. X{    &langtab[5],    "lisp",        getLispId,    setLispArgs    },
  662. X#define    SCAN_TEXT    (&langtab[5])
  663. X{    &langtab[6],    "text",        getTextId,    setTextArgs    },
  664. X#define    SCAN_ROFF    (&langtab[6])
  665. X{    &langtab[7],    "roff",        getRoffId,    setRoffArgs    },
  666. X#define    SCAN_TEX    (&langtab[7])
  667. X{    &langtab[8],    "tex",        getTeXId,    setTeXArgs    },
  668. X{ NULL, NULL, NULL, NULL }
  669. X};
  670. X
  671. X/*
  672. X    This is a rather incomplete list of default associations
  673. X    between suffixes and languages.  You may add more to the
  674. X    default list, or you may define them dynamically with the
  675. X    `-S<suff>=<lang>' argument to mkid(1) and idx(1).  e.g. to
  676. X    associate a `.ada' suffix with the Ada language, use
  677. X    `-S.ada=ada'
  678. X*/
  679. Xstruct sufftab sufftab[] = {
  680. X{    &sufftab[1],    ".c",    SCAN_C        },
  681. X{    &sufftab[2],    ".h",    SCAN_C        },
  682. X{    &sufftab[3],    ".y",    SCAN_C        },
  683. X{    &sufftab[4],    ".s",    SCAN_ASM    },
  684. X{    &sufftab[5],    ".p",    SCAN_PASCAL    },
  685. X{    &sufftab[6],    ".pas",    SCAN_PASCAL    },
  686. X{ NULL, NULL, NULL },
  687. X};
  688. X
  689. X/*
  690. X    Return an index into the langtab array for the given suffix.
  691. X*/
  692. Xstatic struct sufftab *
  693. XsuffSlot(suffix)
  694. X    register char    *suffix;
  695. X{
  696. X    register struct sufftab    *stp;
  697. X
  698. X    if (suffix == NULL)
  699. X        suffix = "";
  700. X
  701. X    for (stp = sufftab; stp->st_next; stp = stp->st_next)
  702. X        if (strequ(stp->st_suffix, suffix))
  703. X            return stp;
  704. X    return stp;
  705. X}
  706. X
  707. Xstatic struct langtab *
  708. XlangSlot(lang)
  709. X    char        *lang;
  710. X{
  711. X    register struct langtab    *ltp;
  712. X
  713. X    if (lang == NULL)
  714. X        lang = "";
  715. X
  716. X    for (ltp = langtab; ltp->lt_next; ltp = ltp->lt_next)
  717. X        if (strequ(ltp->lt_name, lang))
  718. X            return ltp;
  719. X    return ltp;
  720. X}
  721. X
  722. Xchar *
  723. XgetLanguage(suffix)
  724. X    char        *suffix;
  725. X{
  726. X    struct sufftab    *stp;
  727. X
  728. X    if ((stp = suffSlot(suffix))->st_next == NULL)
  729. X        return NULL;
  730. X    return (stp->st_lang->lt_name);
  731. X}
  732. X
  733. Xchar *(*
  734. XgetScanner(lang))()
  735. X    char        *lang;
  736. X{
  737. X    struct langtab    *ltp;
  738. X
  739. X    if ((ltp = langSlot(lang))->lt_next == NULL)
  740. X        return NULL;
  741. X    return (ltp->lt_getid);
  742. X}
  743. X
  744. Xstatic void
  745. Xusage()
  746. X{
  747. X    fprintf(stderr, "Usage: %s [-S<suffix>=<lang>] [+S(+|-)<arg>] [-S<lang>(+|-)<arg>]\n", MyName);
  748. X    exit(1);
  749. X}
  750. Xvoid
  751. XsetScanArgs(op, arg)
  752. X    int        op;
  753. X    char        *arg;
  754. X{
  755. X    struct langtab    *ltp;
  756. X    struct sufftab    *stp;
  757. X    char        *lhs;
  758. X    int        count = 0;
  759. X
  760. X    lhs = arg;
  761. X    while (isalnum(*arg) || *arg == '.')
  762. X        arg++;
  763. X
  764. X    if (strequ(lhs, "?=?")) {
  765. X        for (stp = sufftab; stp->st_next; stp = stp->st_next)
  766. X            printf("%s%s=%s", (count++>0)?", ":"", stp->st_suffix, stp->st_lang->lt_name);
  767. X        if (count)
  768. X            putchar('\n');
  769. X        return;
  770. X    }
  771. X
  772. X    if (strnequ(lhs, "?=", 2)) {
  773. X        lhs += 2;
  774. X        if ((ltp = langSlot(lhs))->lt_next == NULL) {
  775. X            printf("No scanner for language `%s'\n", lhs);
  776. X            return;
  777. X        }
  778. X        for (stp = sufftab; stp->st_next; stp = stp->st_next)
  779. X            if (stp->st_lang == ltp)
  780. X                printf("%s%s=%s", (count++>0)?", ":"", stp->st_suffix, ltp->lt_name);
  781. X        if (count)
  782. X            putchar('\n');
  783. X        return;
  784. X    }
  785. X
  786. X    if (strequ(arg, "=?")) {
  787. X        lhs[strlen(lhs)-2] = '\0';
  788. X        if ((stp = suffSlot(lhs))->st_next == NULL) {
  789. X            printf("No scanner assigned to suffix `%s'\n", lhs);
  790. X            return;
  791. X        }
  792. X        printf("%s=%s\n", stp->st_suffix, stp->st_lang->lt_name);
  793. X        return;
  794. X    }
  795. X
  796. X    if (*arg == '=') {
  797. X        *arg++ = '\0';
  798. X        
  799. X        if ((ltp = langSlot(arg))->lt_next == NULL) {
  800. X            fprintf(stderr, "%s: Language undefined: %s\n", MyName, arg);
  801. X            return;
  802. X        }
  803. X        if ((stp = suffSlot(lhs))->st_next == NULL) {
  804. X            stp->st_suffix = lhs;
  805. X            stp->st_lang = ltp;
  806. X            stp->st_next = NEW(struct sufftab);
  807. X        } else if (!strequ(arg, stp->st_lang->lt_name)) {
  808. X            fprintf(stderr, "%s: Note: `%s=%s' overrides `%s=%s'\n", MyName, lhs, arg, lhs, stp->st_lang->lt_name);
  809. X            stp->st_lang = ltp;
  810. X        }
  811. X        return;
  812. X    }
  813. X    
  814. X    if (op == '+') {
  815. X        switch (op = *arg++)
  816. X        {
  817. X        case '+':
  818. X        case '-':
  819. X        case '?':
  820. X            break;
  821. X        default:
  822. X            usage();
  823. X        }
  824. X        for (ltp = langtab; ltp->lt_next; ltp = ltp->lt_next)
  825. X            (*ltp->lt_setargs)(NULL, op, arg);
  826. X        return;
  827. X    }
  828. X
  829. X    if (*arg == '-' || *arg == '+' || *arg == '?') {
  830. X        op = *arg;
  831. X        *arg++ = '\0';
  832. X        
  833. X        if ((ltp = langSlot(lhs))->lt_next == NULL) {
  834. X            fprintf(stderr, "%s: Language undefined: %s\n", MyName, lhs);
  835. X            return;
  836. X        }
  837. X        (*ltp->lt_setargs)(lhs, op, arg);
  838. X        return;
  839. X    }
  840. X
  841. X    usage();
  842. X}
  843. X
  844. X/*
  845. X    Notify user of unimplemented scanners.
  846. X*/
  847. Xstatic void
  848. XsorryNoScan(lang)
  849. X    char        *lang;
  850. X{
  851. X    if (lang == NULL)
  852. X        return;
  853. X    fprintf(stderr, "Sorry, no scanner is implemented for %s...\n", lang);
  854. X}
  855. SHAR_EOF
  856. if test 5672 -ne "`wc -c < 'getscan.c'`"
  857. then
  858.     echo shar: error transmitting "'getscan.c'" '(should have been 5672 characters)'
  859. fi
  860. echo shar: extracting "'hash.c'" '(2203 characters)'
  861. sed 's/^X//' << \SHAR_EOF > 'hash.c'
  862. X/* Copyright (c) 1986, Greg McGary */
  863. Xstatic char sccsid[] = "@(#)hash.c    1.1 86/10/09";
  864. X
  865. Xchar *hashSearch();
  866. Xint h1str();
  867. Xint h2str();
  868. X
  869. X/*
  870. X    Look for `key' in the hash table starting at address `base'.
  871. X    `base' is a table containing `nel' elements of size `width'.
  872. X    The hashing strategy we use is open addressing.  Apply the
  873. X    primary hash function `h1' and the secondary hash function
  874. X    `h2' when searching for `key' or an empty slot.  `compar'
  875. X    is the comparison function that should be used to compare
  876. X    the key with an element of the table.  It is called with two
  877. X    arguments.  The first argument is the address of the key, and
  878. X    the second argument is the address of the hash table element
  879. X    in question.  `compar' should return 0 if the key matches the
  880. X    element or the empty slot, and non-zero otherwise.
  881. X
  882. X    If a pointer to a long is provided for `probes' we will keep
  883. X    a running total of open addressing hash probes.
  884. X*/
  885. Xchar *
  886. XhashSearch(key, base, nel, width, h1, h2, compar, probes)
  887. X    char        *key;        /* key to locate */
  888. X    char        *base;        /* base of hash table */
  889. X    register int    nel;        /* number of elements in table */
  890. X    int        width;        /* width of each element */
  891. X    int        (*h1)();    /* primary hash function */
  892. X    int        (*h2)();    /* secondary hash function */
  893. X    int        (*compar)();    /* key comparison function */
  894. X    long        *probes;
  895. X{
  896. X    register int    hash1;
  897. X    register int    hash2;
  898. X    register char    *slot;
  899. X
  900. X    hash1 = (*h1)(key) % nel;
  901. X    slot = &base[hash1 * width];
  902. X
  903. X    if (probes)
  904. X        (*probes)++;
  905. X    if ((*compar)(key, slot) == 0)
  906. X        return slot;
  907. X
  908. X    hash2 = (*h2)(key);
  909. X    for (;;) {
  910. X        hash1 = (hash1 + hash2) % nel;
  911. X        slot = &base[hash1 * width];
  912. X
  913. X        if (probes)
  914. X            (*probes)++;
  915. X        if ((*compar)(key, slot) == 0)
  916. X            return slot;
  917. X    }
  918. X}
  919. X
  920. X#define    ABS(n)        ((n) < 0 ? -(n) : (n))
  921. X
  922. X/*
  923. X    A Primary hash function for string keys.
  924. X*/
  925. Xint
  926. Xh1str(key)
  927. X    register char    *key;
  928. X{
  929. X    register int    sum;
  930. X    register int    s;
  931. X
  932. X    for (sum = s = 0; *key; s++)
  933. X        sum += ((*key++) << s);
  934. X
  935. X    return ABS(sum);
  936. X}
  937. X
  938. X/*
  939. X    A Secondary hash function for string keys.
  940. X*/
  941. Xint
  942. Xh2str(key)
  943. X    register char    *key;
  944. X{
  945. X    register int    sum;
  946. X    register int    s;
  947. X    char        *keysav;
  948. X
  949. X    keysav = key;
  950. X    key = &key[strlen(key)];
  951. X
  952. X    for (sum = s = 0; key > keysav; s++)
  953. X        sum += ((*--key) << s);
  954. X
  955. X    return ABS(sum) | 1;
  956. X}
  957. SHAR_EOF
  958. if test 2203 -ne "`wc -c < 'hash.c'`"
  959. then
  960.     echo shar: error transmitting "'hash.c'" '(should have been 2203 characters)'
  961. fi
  962. echo shar: extracting "'idx.c'" '(1358 characters)'
  963. sed 's/^X//' << \SHAR_EOF > 'idx.c'
  964. Xstatic char copyright[] = "@(#)Copyright (c) 1986, Greg McGary";
  965. Xstatic char sccsid[] = "@(#)idx.c    1.2 86/10/17";
  966. X
  967. X#include    <stdio.h>
  968. X#include    <string.h>
  969. X#include    <id.h>
  970. X#include    <extern.h>
  971. X
  972. Xvoid idxtract();
  973. X
  974. Xchar    *MyName;
  975. Xstatic void
  976. Xusage()
  977. X{
  978. X    fprintf(stderr, "Usage: %s [-u] [+/-a<ccc>] [-c<ccc>] files\n", MyName);
  979. X    exit(1);
  980. X}
  981. Xmain(argc, argv)
  982. X    int        argc;
  983. X    char        **argv;
  984. X{
  985. X    char        *arg;
  986. X    int        op;
  987. X    char        *sccsDir = NULL;
  988. X    char        *rcsDir = NULL;
  989. X
  990. X    MyName = basename(GETARG(argc, argv));
  991. X    while (argc) {
  992. X        arg = GETARG(argc, argv);
  993. X        switch (op = *arg++)
  994. X        {
  995. X        case '-':
  996. X        case '+':
  997. X            break;
  998. X        default:
  999. X            UNGETARG(argc, argv);
  1000. X            goto argsdone;
  1001. X        }
  1002. X        switch (*arg++)
  1003. X        {
  1004. X        case 's': sccsDir = arg; break;
  1005. X        case 'r': rcsDir = arg; break;
  1006. X        case 'S': setScanArgs(op, arg); break;
  1007. X        default: usage();
  1008. X        }
  1009. X    }
  1010. Xargsdone:
  1011. X
  1012. X    if (argc == 0)
  1013. X        usage();
  1014. X    while (argc)
  1015. X        idxtract(GETARG(argc, argv), sccsDir, rcsDir);
  1016. X    exit(0);
  1017. X}
  1018. X
  1019. Xvoid
  1020. Xidxtract(path, sccsDir, rcsDir)
  1021. X    char        *path;
  1022. X    char        *sccsDir;
  1023. X    char        *rcsDir;
  1024. X{
  1025. X    register char    *key;
  1026. X    register char    *(*getId)();
  1027. X    register FILE    *srcFILE;
  1028. X    char        *(*getScanner())();
  1029. X    int        flags;
  1030. X
  1031. X    if ((getId = getScanner(getLanguage(strrchr(path, '.')))) == NULL)
  1032. X        return;
  1033. X    if ((srcFILE = openSrcFILE(path, sccsDir, rcsDir)) == NULL)
  1034. X        return;
  1035. X
  1036. X    while ((key = (*getId)(srcFILE, &flags)) != NULL)
  1037. X        puts(key);
  1038. X
  1039. X    fclose(srcFILE);
  1040. X}
  1041. SHAR_EOF
  1042. if test 1358 -ne "`wc -c < 'idx.c'`"
  1043. then
  1044.     echo shar: error transmitting "'idx.c'" '(should have been 1358 characters)'
  1045. fi
  1046. echo shar: extracting "'init.c'" '(1259 characters)'
  1047. sed 's/^X//' << \SHAR_EOF > 'init.c'
  1048. X/* Copyright (c) 1986, Greg McGary */
  1049. Xstatic char sccsid[] = "@(#)init.c    1.1 86/10/09";
  1050. X
  1051. X#include    <id.h>
  1052. X#include    <string.h>
  1053. X#include    <stdio.h>
  1054. X#include    <extern.h>
  1055. X
  1056. XFILE *
  1057. XinitID(idFile, idhp, idArgs)
  1058. X    char        *idFile;
  1059. X    struct idhead    *idhp;
  1060. X    struct idarg    **idArgs;
  1061. X{
  1062. X    FILE        *idFILE;
  1063. X    register int    i;
  1064. X    register char    *strings;
  1065. X    register struct idarg    *idArg;
  1066. X
  1067. X    if ((idFILE = fopen(idFile, "r")) == NULL)
  1068. X        return NULL;
  1069. X
  1070. X    fseek(idFILE, 0L, 0);
  1071. X    fread(idhp, sizeof(struct idhead), 1, idFILE);
  1072. X    if (!strnequ(idhp->idh_magic, IDH_MAGIC, sizeof(idhp->idh_magic))) {
  1073. X        fprintf(stderr, "%s: Not an id file: `%s'\n", MyName, idFile);
  1074. X        exit(1);
  1075. X    }
  1076. X    if (idhp->idh_vers != IDH_VERS) {
  1077. X        fprintf(stderr, "%s: ID version mismatch (want: %d, got: %d)\n", MyName, IDH_VERS, idhp->idh_vers);
  1078. X        exit(1);
  1079. X    }
  1080. X
  1081. X    fseek(idFILE, idhp->idh_argo, 0);
  1082. X    strings = malloc(i = idhp->idh_namo - idhp->idh_argo);
  1083. X    fread(strings, i, 1, idFILE);
  1084. X    idArg = *idArgs = (struct idarg *)calloc(idhp->idh_pthc, sizeof(struct idarg));
  1085. X    for (i = 0; i < idhp->idh_argc; i++) {
  1086. X        if (*strings == '+' || *strings == '-')
  1087. X            goto skip;
  1088. X        idArg->ida_flags = (*strings) ? 0 : IDA_BLANK;
  1089. X        idArg->ida_arg = strings;
  1090. X        idArg->ida_next = idArg + 1;
  1091. X        idArg++;
  1092. X    skip:
  1093. X        while (*strings++)
  1094. X            ;
  1095. X    }
  1096. X    return idFILE;
  1097. X}
  1098. SHAR_EOF
  1099. if test 1259 -ne "`wc -c < 'init.c'`"
  1100. then
  1101.     echo shar: error transmitting "'init.c'" '(should have been 1259 characters)'
  1102. fi
  1103. echo shar: extracting "'lid.c'" '(16134 characters)'
  1104. sed 's/^X//' << \SHAR_EOF > 'lid.c'
  1105. Xstatic char copyright[] = "@(#)Copyright (c) 1986, Greg McGary";
  1106. Xstatic char sccsid[] = "@(#)lid.c    1.4 86/11/06";
  1107. X
  1108. X#include    <bool.h>
  1109. X#include    <stdio.h>
  1110. X#include    <string.h>
  1111. X#include    <ctype.h>
  1112. X#include    <radix.h>
  1113. X#include    <id.h>
  1114. X#include    <bitops.h>
  1115. X#include    <extern.h>
  1116. X
  1117. X#ifdef REGEX
  1118. Xextern char *regex();
  1119. Xextern char *regcmp();
  1120. X#endif
  1121. X#ifdef RE_EXEC
  1122. Xextern char *re_comp();
  1123. Xextern int re_exec();
  1124. X#endif
  1125. X
  1126. Xbool isMagic();
  1127. Xchar **bitsToArgv();
  1128. Xchar *fileRE();
  1129. Xchar *strcpos();
  1130. Xint skipToArgv();
  1131. Xint findAnchor();
  1132. Xint findApropos();
  1133. X#if REGEX || RE_EXEC
  1134. Xint findRegExp();
  1135. X#endif
  1136. Xint findNonUnique();
  1137. Xint findNumber();
  1138. Xint findPlain();
  1139. Xint idCompare();
  1140. Xlong searchName();
  1141. Xvoid editId();
  1142. Xvoid grepId();
  1143. Xvoid lookId();
  1144. X
  1145. X#ifdef USG
  1146. X#define    TOLOWER(c)    (isupper(c) ? _tolower(c) : (c))
  1147. X#else
  1148. X#define    TOLOWER(c)    (isupper(c) ? tolower(c) : (c))
  1149. X#endif
  1150. X
  1151. X/*
  1152. X*  Sorry about all the globals, but it's really cleaner this way.
  1153. X*/
  1154. XFILE        *IdFILE;
  1155. Xbool        Merging;
  1156. Xbool        Radix;
  1157. Xchar        *IdDir;
  1158. Xlong        AnchorOffset;
  1159. Xint        BitArraySize;
  1160. Xstruct idhead    Idh;
  1161. Xstruct idarg    *IdArgs;
  1162. Xint        (*FindFunc)() = NULL;
  1163. Xint        Solo = 0;
  1164. X#define    IGNORE_SOLO(buf) \
  1165. X( \
  1166. X       (Solo == '-' && !(ID_FLAGS(buf) & IDN_SOLO)) \
  1167. X    || (Solo == '+' &&  (ID_FLAGS(buf) & IDN_SOLO)) \
  1168. X)
  1169. X
  1170. Xchar *MyName;
  1171. Xstatic void
  1172. Xusage()
  1173. X{
  1174. X    fprintf(stderr, "Usage: %s [-f<file>] [-u<n>] [-mewdoxas] patterns...\n", MyName);
  1175. X    exit(1);
  1176. X}
  1177. Xmain(argc, argv)
  1178. X    int        argc;
  1179. X    char        **argv;
  1180. X{
  1181. X    char        *idFile = IDFILE;
  1182. X    char        *arg;
  1183. X    long        val;
  1184. X    void        (*doit)();
  1185. X    bool        forceMerge = FALSE;
  1186. X    int        uniqueLimit = 0;
  1187. X    int        op;
  1188. X
  1189. X    MyName = basename(GETARG(argc, argv));
  1190. X
  1191. X    while (argc) {
  1192. X        arg = GETARG(argc, argv);
  1193. X        switch (op = *arg++)
  1194. X        {
  1195. X        case '-':
  1196. X        case '+':
  1197. X            break;
  1198. X        default:
  1199. X            UNGETARG(argc, argv);
  1200. X            goto argsdone;
  1201. X        }
  1202. X        while (*arg) switch (*arg++)
  1203. X        {
  1204. X        case 'f': idFile = arg; goto nextarg;
  1205. X        case 'u': uniqueLimit = stoi(arg); goto nextarg;
  1206. X        case 'm': forceMerge = TRUE; break;
  1207. X#if REGEX || RE_EXEC
  1208. X        case 'e': FindFunc = findRegExp; break;
  1209. X#endif
  1210. X        case 'w': FindFunc = findPlain; break;
  1211. X        case 'd': Radix |= RADIX_DEC; break;
  1212. X        case 'o': Radix |= RADIX_OCT; break;
  1213. X        case 'x': Radix |= RADIX_HEX; break;
  1214. X        case 'a': Radix |= RADIX_ALL; break;
  1215. X        case 's': Solo = op; break;
  1216. X        default:
  1217. X            usage();
  1218. X        }
  1219. X    nextarg:;
  1220. X    }
  1221. Xargsdone:
  1222. X
  1223. X    IdDir = getDirToName(idFile);
  1224. X    idFile = spanPath(IdDir, idFile);
  1225. X    if ((IdFILE = initID(idFile, &Idh, &IdArgs)) == NULL) {
  1226. X        filerr("open", idFile);
  1227. X        exit(1);
  1228. X    }
  1229. X    BitArraySize = (Idh.idh_pthc + 7) >> 3;
  1230. X
  1231. X    switch (MyName[0])
  1232. X    {
  1233. X    case 'a':
  1234. X        FindFunc = findApropos;
  1235. X        /*FALLTHROUGH*/
  1236. X    case 'l':
  1237. X        doit = lookId;
  1238. X        break;
  1239. X    case 'g':
  1240. X        doit = grepId;
  1241. X        break;
  1242. X    case 'e':
  1243. X        doit = editId;
  1244. X        break;
  1245. X    default:
  1246. X        MyName = "[alge]id";
  1247. X        usage();
  1248. X    }
  1249. X
  1250. X    if (argc == 0) {
  1251. X        UNGETARG(argc, argv);
  1252. X        *argv = ".";
  1253. X    }
  1254. X
  1255. X    while (argc) {
  1256. X        arg = GETARG(argc, argv);
  1257. X        if (FindFunc)
  1258. X            ;
  1259. X        else if ((radix(arg)) && (val = stoi(arg)) >= 0)
  1260. X            FindFunc = findNumber;
  1261. X#if REGEX || RE_EXEC
  1262. X        else if (isMagic(arg))
  1263. X            FindFunc = findRegExp;
  1264. X#endif
  1265. X        else if (arg[0] == '^')
  1266. X            FindFunc = findAnchor;
  1267. X        else
  1268. X            FindFunc = findPlain;
  1269. X
  1270. X        if ((doit == lookId && !forceMerge)
  1271. X        || (FindFunc == findNumber && bitCount(Radix) > 1 && val > 7))
  1272. X            Merging = FALSE;
  1273. X        else
  1274. X            Merging = TRUE;
  1275. X
  1276. X        if (uniqueLimit) {
  1277. X            if (!findNonUnique(uniqueLimit, doit))
  1278. X                fprintf(stderr, "All identifiers are unique within the first %d characters\n", uniqueLimit);
  1279. X            exit(0);
  1280. X        } else if (!(*FindFunc)(arg, doit)) {
  1281. X            fprintf(stderr, "%s: not found\n", arg);
  1282. X            continue;
  1283. X        }
  1284. X    }
  1285. X    exit(0);
  1286. X}
  1287. X
  1288. Xvoid
  1289. XlookId(name, argv)
  1290. X    char        *name;
  1291. X    register char    **argv;
  1292. X{
  1293. X    register char    *arg;
  1294. X    register bool    crunching = FALSE;
  1295. X    register char    *dir;
  1296. X
  1297. X    printf("%-14s ", name);
  1298. X    while (*argv) {
  1299. X        arg = *argv++;
  1300. X        if (*argv && canCrunch(arg, *argv)) {
  1301. X            if (crunching)
  1302. X                printf(",%s", rootName(arg));
  1303. X            else if ((dir = dirname(arg)) && dir[0] == '.' && dir[1] == '\0')
  1304. X                printf("{%s", rootName(arg));
  1305. X            else
  1306. X                printf("%s/{%s", dir, rootName(arg));
  1307. X            /*}}*/
  1308. X            crunching = TRUE;
  1309. X        } else {
  1310. X            if (crunching) /*{*/
  1311. X                printf(",%s}%s", rootName(arg), suffName(arg));
  1312. X            else
  1313. X                fputs(arg, stdout);
  1314. X            crunching = FALSE;
  1315. X            if (*argv)
  1316. X                putchar(' ');
  1317. X        }
  1318. X    }
  1319. X    putchar('\n');
  1320. X}
  1321. X
  1322. Xvoid
  1323. XgrepId(name, argv)
  1324. X    char        *name;
  1325. X    char        **argv;
  1326. X{
  1327. X    FILE        *gidFILE;
  1328. X    char        *gidName;
  1329. X    char        buf[BUFSIZ];
  1330. X    char        *delimit = "[^a-zA-Z0-9_]";
  1331. X    char        *re;
  1332. X    char        *reCompiled;
  1333. X    int        lineNumber;
  1334. X
  1335. X    if (!Merging || (re = fileRE(name, delimit, delimit)) == NULL)
  1336. X        re = NULL;
  1337. X#ifdef REGEX
  1338. X    else if ((reCompiled = regcmp(re, 0)) == NULL) {
  1339. X        fprintf(stderr, "%s: Syntax Error: %s\n", MyName, re);
  1340. X        return;
  1341. X    }
  1342. X#endif
  1343. X#ifdef RE_EXEC
  1344. X    else if ((reCompiled = re_comp(re)) != NULL) {
  1345. X        fprintf(stderr, "%s: Syntax Error: %s (%s)\n", MyName, re, reCompiled);
  1346. X        return;
  1347. X    }
  1348. X#endif
  1349. X
  1350. X    buf[0] = ' ';    /* sentry */
  1351. X    while (*argv) {
  1352. X        if ((gidFILE = fopen(gidName = *argv++, "r")) == NULL) {
  1353. X            filerr("open", gidName);
  1354. X            continue;
  1355. X        }
  1356. X        lineNumber = 0;
  1357. X        while (fgets(&buf[1], sizeof(buf), gidFILE)) {
  1358. X            lineNumber++;
  1359. X            if (re) {
  1360. X#ifdef REGEX
  1361. X                if (regex(reCompiled, buf) == NULL)
  1362. X#endif
  1363. X#ifdef RE_EXEC
  1364. X                if (!re_exec(buf))
  1365. X#endif
  1366. X                    continue;
  1367. X            } else if (!wordMatch(name, buf))
  1368. X                continue;
  1369. X            printf("%s:%d: %s", gidName, lineNumber, &buf[1]);
  1370. X        }
  1371. X        fclose(gidFILE);
  1372. X    }
  1373. X}
  1374. X
  1375. Xvoid
  1376. XeditId(name, argv)
  1377. X    char        *name;
  1378. X    char        **argv;
  1379. X{
  1380. X    char        reBuf[BUFSIZ];
  1381. X    char        edArgBuf[BUFSIZ];
  1382. X    char        *re;
  1383. X    int        c;
  1384. X    int        skip;
  1385. X    static char    *editor, *eidArg, *eidRightDel, *eidLeftDel;
  1386. X
  1387. X    if (editor == NULL && (editor = getenv("EDITOR")) == NULL) {
  1388. X        char    *ucb_vi = "/usr/ucb/vi";
  1389. X        char    *bin_vi = "/usr/bin/vi";
  1390. X
  1391. X        if (access(ucb_vi, 01) == 0)
  1392. X            editor = ucb_vi;
  1393. X        else if (access(bin_vi, 01) == 0)
  1394. X            editor = bin_vi;
  1395. X        else
  1396. X            editor = "/bin/ed";    /* YUCK! */
  1397. X        if (editor == ucb_vi || editor == bin_vi) {
  1398. X            eidArg = "+1;/%s/";
  1399. X            eidLeftDel = "\\<";
  1400. X            eidRightDel = "\\>";
  1401. X        }
  1402. X    }
  1403. X    if (eidLeftDel == NULL) {
  1404. X        eidArg = getenv("EIDARG");
  1405. X        if ((eidLeftDel = getenv("EIDLDEL")) == NULL)
  1406. X            eidLeftDel = "";
  1407. X        if ((eidRightDel = getenv("EIDRDEL")) == NULL)
  1408. X            eidRightDel = "";
  1409. X    }
  1410. X
  1411. X    lookId(name, argv);
  1412. X    savetty();
  1413. X    for (;;) {
  1414. X        printf("Edit? [y1-9^S/nq] "); fflush(stdout);
  1415. X        chartty();
  1416. X        c = (getchar() & 0177);
  1417. X        restoretty();
  1418. X        switch (TOLOWER(c))
  1419. X        {
  1420. X        case '/': case ('s'&037):
  1421. X            putchar('/');
  1422. X            /*FALLTHROUGH*/
  1423. X            if ((skip = skipToArgv(argv)) < 0)
  1424. X                continue;
  1425. X            argv += skip;
  1426. X            goto editit;
  1427. X        case '1': case '2': case '3': case '4':
  1428. X        case '5': case '6': case '7': case '8': case '9':
  1429. X            putchar(c);
  1430. X            skip = c - '0';
  1431. X            break;
  1432. X        case 'y':
  1433. X            putchar(c);
  1434. X            /*FALLTHROUGH*/
  1435. X        case '\n':
  1436. X        case '\r':
  1437. X            skip = 0;
  1438. X            break;
  1439. X        case 'q':
  1440. X            putchar(c);
  1441. X            putchar('\n');
  1442. X            exit(0);
  1443. X        case 'n':
  1444. X            putchar(c);
  1445. X            putchar('\n');
  1446. X            return;
  1447. X        default:
  1448. X            putchar(c);
  1449. X            putchar('\n');
  1450. X            continue;
  1451. X        }
  1452. X
  1453. X        putchar('\n');
  1454. X        while (skip--)
  1455. X            if (*++argv == NULL)
  1456. X                continue;
  1457. X        break;
  1458. X    }
  1459. Xeditit:
  1460. X
  1461. X    if (!Merging || (re = fileRE(name, eidLeftDel, eidRightDel)) == NULL)
  1462. X        sprintf(re = reBuf, "%s%s%s", eidLeftDel, name, eidRightDel);
  1463. X
  1464. X    switch (fork())
  1465. X    {
  1466. X    case -1:
  1467. X        fprintf(stderr, "%s: Cannot fork (%s)\n", MyName, uerror());
  1468. X        exit(1);
  1469. X    case 0:
  1470. X        argv--;
  1471. X        if (eidArg) {
  1472. X            argv--;
  1473. X            sprintf(edArgBuf, eidArg, re);
  1474. X            argv[1] = edArgBuf;
  1475. X        }
  1476. X        argv[0] = editor;
  1477. X        execv(editor, argv);
  1478. X        filerr("exec", editor);
  1479. X    default:
  1480. X        wait(0);
  1481. X        break;
  1482. X    }
  1483. X}
  1484. X
  1485. Xint
  1486. XskipToArgv(argv)
  1487. X    char        **argv;
  1488. X{
  1489. X    char        pattern[BUFSIZ];
  1490. X    int        count;
  1491. X
  1492. X    if (gets(pattern) == NULL)
  1493. X        return -1;
  1494. X    
  1495. X    for (count = 0; *argv; count++, argv++)
  1496. X        if (strcpos(*argv, pattern))
  1497. X            return count;
  1498. X    return -1;
  1499. X}
  1500. X
  1501. Xint
  1502. XfindPlain(arg, doit)
  1503. X    char        *arg;
  1504. X    void        (*doit)();
  1505. X{
  1506. X    static char    *buf, *bitArray;
  1507. X    int        size;
  1508. X
  1509. X    if (searchName(arg) == 0)
  1510. X        return 0;
  1511. X    if (buf == NULL) {
  1512. X        buf = malloc(Idh.idh_bsiz);
  1513. X        bitArray = malloc(BitArraySize);
  1514. X    }
  1515. X    bzero(bitArray, BitArraySize);
  1516. X
  1517. X    if ((size = fgets0(buf, Idh.idh_bsiz, IdFILE)) == 0)
  1518. X        return 0;
  1519. X    size++;
  1520. X    getsFF(&buf[size], IdFILE);
  1521. X    if (IGNORE_SOLO(buf))
  1522. X        return 0;
  1523. X
  1524. X    vecToBits(bitArray, &buf[size], Idh.idh_vecc);
  1525. X    (*doit)(ID_STRING(buf), bitsToArgv(bitArray));
  1526. X    return 1;
  1527. X}
  1528. X
  1529. Xint
  1530. XfindAnchor(arg, doit)
  1531. X    register char    *arg;
  1532. X    void        (*doit)();
  1533. X{
  1534. X    static char    *buf, *bitArray;
  1535. X    int        count, size;
  1536. X    int        len;
  1537. X
  1538. X    if (searchName(++arg) == 0)
  1539. X        return 0;
  1540. X
  1541. X    if (buf == NULL) {
  1542. X        buf = malloc(Idh.idh_bsiz);
  1543. X        bitArray = malloc(BitArraySize);
  1544. X    }
  1545. X    bzero(bitArray, BitArraySize);
  1546. X
  1547. X    len = strlen(arg);
  1548. X    count = 0;
  1549. X    while ((size = fgets0(buf, Idh.idh_bsiz, IdFILE)) > 0) {
  1550. X        size++;
  1551. X        getsFF(&buf[size], IdFILE);
  1552. X        if (IGNORE_SOLO(buf))
  1553. X            continue;
  1554. X        if (!strnequ(arg, ID_STRING(buf), len))
  1555. X            break;
  1556. X        vecToBits(bitArray, &buf[size], Idh.idh_vecc);
  1557. X        if (!Merging) {
  1558. X            (*doit)(ID_STRING(buf), bitsToArgv(bitArray));
  1559. X            bzero(bitArray, BitArraySize);
  1560. X        }
  1561. X        count++;
  1562. X    }
  1563. X    if (Merging && count)
  1564. X        (*doit)(--arg, bitsToArgv(bitArray));
  1565. X
  1566. X    return count;
  1567. X}
  1568. X
  1569. X#if REGEX || RE_EXEC
  1570. Xint
  1571. XfindRegExp(re, doit)
  1572. X    char        *re;
  1573. X    void        (*doit)();
  1574. X{
  1575. X    static char    *buf, *bitArray;
  1576. X    int        count, size;
  1577. X    char        *reCompiled;
  1578. X
  1579. X#ifdef REGEX
  1580. X    if ((reCompiled = regcmp(re, 0)) == NULL) {
  1581. X        fprintf(stderr, "%s: Syntax Error: %s\n", MyName, re);
  1582. X        return 0;
  1583. X    }
  1584. X#endif
  1585. X#ifdef RE_EXEC
  1586. X    if ((reCompiled = re_comp(re)) != NULL) {
  1587. X        fprintf(stderr, "%s: Syntax Error: %s (%s)\n", MyName, re, reCompiled);
  1588. X        return 0;
  1589. X    }
  1590. X#endif
  1591. X    fseek(IdFILE, Idh.idh_namo, 0);
  1592. X
  1593. X    if (buf == NULL) {
  1594. X        buf = malloc(Idh.idh_bsiz);
  1595. X        bitArray = malloc(BitArraySize);
  1596. X    }
  1597. X    bzero(bitArray, BitArraySize);
  1598. X
  1599. X    count = 0;
  1600. X    while ((size = fgets0(buf, Idh.idh_bsiz, IdFILE)) > 0) {
  1601. X        size++;
  1602. X        getsFF(&buf[size], IdFILE);
  1603. X        if (IGNORE_SOLO(buf))
  1604. X            continue;
  1605. X#ifdef REGEX
  1606. X        if (regex(reCompiled, ID_STRING(buf)) == NULL)
  1607. X#endif
  1608. X#ifdef RE_EXEC
  1609. X        if (!re_exec(ID_STRING(buf)))
  1610. X#endif
  1611. X            continue;
  1612. X        vecToBits(bitArray, &buf[size], Idh.idh_vecc);
  1613. X        if (!Merging) {
  1614. X            (*doit)(ID_STRING(buf), bitsToArgv(bitArray));
  1615. X            bzero(bitArray, BitArraySize);
  1616. X        }
  1617. X        count++;
  1618. X    }
  1619. X    if (Merging && count)
  1620. X        (*doit)(re, bitsToArgv(bitArray));
  1621. X
  1622. X    return count;
  1623. X}
  1624. X#endif
  1625. X
  1626. Xint
  1627. XfindNumber(arg, doit)
  1628. X    char        *arg;
  1629. X    void        (*doit)();
  1630. X{
  1631. X    static char    *buf, *bitArray;
  1632. X    int        count, size;
  1633. X    register int    rdx = 0;
  1634. X    register int    val;
  1635. X    register bool    hitDigits = FALSE;
  1636. X
  1637. X    if ((val = stoi(arg)) <= 7)
  1638. X        rdx |= RADIX_ALL;
  1639. X    else
  1640. X        rdx = radix(arg);
  1641. X    fseek(IdFILE, Idh.idh_namo, 0);
  1642. X
  1643. X    if (buf == NULL) {
  1644. X        buf = malloc(Idh.idh_bsiz);
  1645. X        bitArray = malloc(BitArraySize);
  1646. X    }
  1647. X    bzero(bitArray, BitArraySize);
  1648. X
  1649. X    count = 0;
  1650. X    while ((size = fgets0(buf, Idh.idh_bsiz, IdFILE)) > 0) {
  1651. X        size++;
  1652. X        getsFF(&buf[size], IdFILE);
  1653. X        if (hitDigits) {
  1654. X            if (!isdigit(*ID_STRING(buf)))
  1655. X                break;
  1656. X        } else if (isdigit(*ID_STRING(buf)))
  1657. X            hitDigits = TRUE;
  1658. X
  1659. X        if (!((Radix ? Radix : rdx) & radix(ID_STRING(buf)))
  1660. X        || stoi(ID_STRING(buf)) != val)
  1661. X            continue;
  1662. X        vecToBits(bitArray, &buf[size], Idh.idh_vecc);
  1663. X        if (!Merging) {
  1664. X            (*doit)(ID_STRING(buf), bitsToArgv(bitArray));
  1665. X            bzero(bitArray, BitArraySize);
  1666. X        }
  1667. X        count++;
  1668. X    }
  1669. X    if (Merging && count)
  1670. X        (*doit)(arg, bitsToArgv(bitArray));
  1671. X
  1672. X    return count;
  1673. X}
  1674. X
  1675. X/*
  1676. X    Find identifiers that are non-unique within
  1677. X    the first `count' characters.
  1678. X*/
  1679. Xint
  1680. XfindNonUnique(limit, doit)
  1681. X    int        limit;
  1682. X    void        (*doit)();
  1683. X{
  1684. X    static char    *buf1, *buf2, *bitArray;
  1685. X    register char    *old;
  1686. X    register char    *new;
  1687. X    register int    consecutive;
  1688. X    char        *cptmp;
  1689. X    int        itmp;
  1690. X    int        count, oldsize, newsize;
  1691. X    char        *name;
  1692. X
  1693. X    if (limit <= 1)
  1694. X        usage();
  1695. X
  1696. X    fseek(IdFILE, Idh.idh_namo, 0);
  1697. X
  1698. X    if (buf1 == NULL) {
  1699. X        buf1 = malloc(Idh.idh_bsiz);
  1700. X        buf2 = malloc(Idh.idh_bsiz);
  1701. X        bitArray = malloc(BitArraySize);
  1702. X    }
  1703. X    bzero(bitArray, BitArraySize);
  1704. X
  1705. X    name = calloc(1, limit+2);
  1706. X    name[0] = '^';
  1707. X    old = buf1;
  1708. X    *ID_STRING(new = buf2) = '\0';
  1709. X    count = consecutive = 0;
  1710. X    while ((oldsize = fgets0(old, Idh.idh_bsiz, IdFILE)) > 0) {
  1711. X        oldsize++;
  1712. X        getsFF(&old[oldsize], IdFILE);
  1713. X        if (!(ID_FLAGS(old) & IDN_NAME))
  1714. X            continue;
  1715. X        cptmp = old; old = new; new = cptmp;
  1716. X        itmp = oldsize; oldsize = newsize; newsize = itmp;
  1717. X        if (!strnequ(ID_STRING(new), ID_STRING(old), limit)) {
  1718. X            if (consecutive && Merging) {
  1719. X                strncpy(&name[1], ID_STRING(old), limit); 
  1720. X                (*doit)(name, bitsToArgv(bitArray));
  1721. X            }
  1722. X            consecutive = 0;
  1723. X            continue;
  1724. X        }
  1725. X        if (!consecutive++) {
  1726. X            vecToBits(bitArray, &old[oldsize], Idh.idh_vecc);
  1727. X            if (!Merging) {
  1728. X                (*doit)(ID_STRING(old), bitsToArgv(bitArray));
  1729. X                bzero(bitArray, BitArraySize);
  1730. X            }
  1731. X            count++;
  1732. X        }
  1733. X        vecToBits(bitArray, &new[newsize], Idh.idh_vecc);
  1734. X        if (!Merging) {
  1735. X            (*doit)(ID_STRING(new), bitsToArgv(bitArray));
  1736. X            bzero(bitArray, BitArraySize);
  1737. X        }
  1738. X        count++;
  1739. X    }
  1740. X
  1741. X    return count;
  1742. X}
  1743. X
  1744. Xint
  1745. XfindApropos(arg, doit)
  1746. X    char        *arg;
  1747. X    void        (*doit)();
  1748. X{
  1749. X    static char    *buf, *bitArray;
  1750. X    int        count, size;
  1751. X
  1752. X    fseek(IdFILE, Idh.idh_namo, 0);
  1753. X
  1754. X    if (buf == NULL) {
  1755. X        buf = malloc(Idh.idh_bsiz);
  1756. X        bitArray = malloc(BitArraySize);
  1757. X    }
  1758. X    bzero(bitArray, BitArraySize);
  1759. X
  1760. X    count = 0;
  1761. X    while ((size = fgets0(buf, Idh.idh_bsiz, IdFILE)) > 0) {
  1762. X        size++;
  1763. X        getsFF(&buf[size], IdFILE);
  1764. X        if (IGNORE_SOLO(buf))
  1765. X            continue;
  1766. X        if (strcpos(ID_STRING(buf), arg) == NULL)
  1767. X            continue;
  1768. X        vecToBits(bitArray, &buf[size], Idh.idh_vecc);
  1769. X        if (!Merging) {
  1770. X            (*doit)(ID_STRING(buf), bitsToArgv(bitArray));
  1771. X            bzero(bitArray, BitArraySize);
  1772. X        }
  1773. X        count++;
  1774. X    }
  1775. X    if (Merging && count)
  1776. X        (*doit)(arg, bitsToArgv(bitArray));
  1777. X
  1778. X    return count;
  1779. X}
  1780. X
  1781. X/*
  1782. X    if string `s2' occurs in `s1', return a pointer to the
  1783. X    first match.  Ignore differences in alphabetic case.
  1784. X*/
  1785. Xchar *
  1786. Xstrcpos(s1, s2)
  1787. X    char        *s1;
  1788. X    char        *s2;
  1789. X{
  1790. X    register char    *s1p;
  1791. X    register char    *s2p;
  1792. X    char        *s1last;
  1793. X
  1794. X    for (s1last = &s1[strlen(s1) - strlen(s2)]; s1 <= s1last; s1++)
  1795. X        for (s1p = s1, s2p = s2; TOLOWER(*s1p) == TOLOWER(*s2p); s1p++)
  1796. X            if (*++s2p == '\0')
  1797. X                return s1;
  1798. X    return NULL;
  1799. X}
  1800. X
  1801. X/*
  1802. X    Convert the regular expression that we used to
  1803. X    locate identifiers in the id database into one
  1804. X    suitable for locating the identifiers in files.
  1805. X*/
  1806. Xchar *
  1807. XfileRE(name0, leftDelimit, rightDelimit)
  1808. X    char        *name0;
  1809. X    char        *leftDelimit;
  1810. X    char        *rightDelimit;
  1811. X{
  1812. X    static char    reBuf[BUFSIZ];
  1813. X    register char    *name = name0;
  1814. X
  1815. X    if (FindFunc == findNumber && Merging) {
  1816. X        sprintf(reBuf, "%s0*[Xx]*0*%d[Ll]*%s", leftDelimit, stoi(name), rightDelimit);
  1817. X        return reBuf;
  1818. X    }
  1819. X
  1820. X    if (!isMagic(name) && name[0] != '^')
  1821. X        return NULL;
  1822. X
  1823. X    if (name[0] == '^')
  1824. X        name0++;
  1825. X    else
  1826. X        leftDelimit = "";
  1827. X    while (*++name)
  1828. X        ;
  1829. X    if (*--name == '$')
  1830. X        *name = '\0';
  1831. X    else
  1832. X        rightDelimit = "";
  1833. X
  1834. X    sprintf(reBuf, "%s%s%s", leftDelimit, name0, rightDelimit);
  1835. X    return reBuf;
  1836. X}
  1837. X
  1838. Xlong
  1839. XsearchName(name)
  1840. X    char        *name;
  1841. X{
  1842. X    long        offset;
  1843. X
  1844. X    AnchorOffset = 0;
  1845. X    offset = (long)bsearch(name, (char *)(Idh.idh_namo-1), Idh.idh_endo-(Idh.idh_namo-1), 1, idCompare);
  1846. X    if (offset == 0)
  1847. X        offset = AnchorOffset;
  1848. X    if (offset == 0)
  1849. X        return 0;
  1850. X    fseek(IdFILE, offset, 0);
  1851. X    skipFF(IdFILE);
  1852. X    return ftell(IdFILE);
  1853. X}
  1854. X
  1855. Xint
  1856. XidCompare(key, offset)
  1857. X    register char    *key;
  1858. X    long        offset;
  1859. X{
  1860. X    register int    c;
  1861. X
  1862. X    fseek(IdFILE, offset, 0);
  1863. X    skipFF(IdFILE);
  1864. X    getc(IdFILE);
  1865. X
  1866. X    while (*key == (c = getc(IdFILE)))
  1867. X        if (*key++ == '\0')
  1868. X            return 0;
  1869. X    if (*key == '\0' && FindFunc == findAnchor)
  1870. X        AnchorOffset = offset;
  1871. X
  1872. X    return *key - c;
  1873. X}
  1874. X
  1875. X/*
  1876. X    Are there any magic Regular Expression meta-characters in name??
  1877. X*/
  1878. Xbool
  1879. XisMagic(name)
  1880. X    register char    *name;
  1881. X{
  1882. X    char        *magichar = "[]{}().*+^$";
  1883. X    int        backslash = 0;
  1884. X
  1885. X    if (*name == '^')
  1886. X        name++;
  1887. X    while (*name) {
  1888. X        if (*name == '\\')
  1889. X            name++, backslash++;
  1890. X        else if (strchr(magichar, *name))
  1891. X            return TRUE;
  1892. X        name++;
  1893. X    }
  1894. X    if (backslash)
  1895. X        while (*name) {
  1896. X            if (*name == '\\')
  1897. X                strcpy(name, name+1);
  1898. X            name++;
  1899. X        }
  1900. X    return FALSE;
  1901. X}
  1902. X
  1903. Xchar **
  1904. XbitsToArgv(bitArray)
  1905. X    char        *bitArray;
  1906. X{
  1907. X    static char    **argv;
  1908. X    struct idarg    *idArgs;
  1909. X    register char    **av;
  1910. X    register int    i;
  1911. X#define    ARGV1stPATH    3 /* available argv[] slots before first pathname */
  1912. X
  1913. X    if (argv == NULL)
  1914. X        argv = (char **)malloc(sizeof(char *) * (Idh.idh_pthc + ARGV1stPATH + 2));
  1915. X
  1916. X    av = argv + ARGV1stPATH;
  1917. X    for (idArgs = IdArgs, i = 0; i < Idh.idh_pthc; i++, idArgs++) {
  1918. X        if (!BITTST(bitArray, i))
  1919. X            continue;
  1920. X        if (idArgs->ida_flags & IDA_BLANK) {
  1921. X            printf("BOTCH: blank index!\n");
  1922. X            abort();
  1923. X        }
  1924. X        if (!(idArgs->ida_flags & IDA_ADJUST)) {
  1925. X            idArgs->ida_arg = strsav(spanPath(IdDir, idArgs->ida_arg));
  1926. X            idArgs->ida_flags |= IDA_ADJUST;
  1927. X        }
  1928. X        *av++ = idArgs->ida_arg;
  1929. X    }
  1930. X    *av = NULL;
  1931. X    return (argv + ARGV1stPATH);
  1932. X}
  1933. SHAR_EOF
  1934. if test 16134 -ne "`wc -c < 'lid.c'`"
  1935. then
  1936.     echo shar: error transmitting "'lid.c'" '(should have been 16134 characters)'
  1937. fi
  1938. #    End of shell archive
  1939. exit 0
  1940.